<template>
  <div class="map-container" id="shaoxing-map-app">
    <div class="map-content">
      <!-- Loading 指示器 -->
      <div v-if="loading" class="loading-overlay">
        <div class="loading-spinner">
          <svg viewBox="0 0 50 50" class="spinner">
            <circle cx="25" cy="25" r="20" fill="none" stroke="#ffffff" stroke-width="5" stroke-linecap="round" />
          </svg>
        </div>
        <span class="loading-text">加载中...</span>
      </div>
      <div id="map"></div>

      <!-- 返回上级按钮 -->
      <el-button size="small" class="back-button" v-if="canGoBack" type="primary" @click="goBackToParent"
        >返回上级</el-button
      >
    </div>
  </div>
</template>

<script setup>
import { onMounted, onBeforeUnmount, ref, watch, computed, nextTick } from "vue";
import "ol/ol.css";
import { defaults as defaultInteractions } from "ol/interaction";
import { Map, View } from "ol";
import { DoubleClickZoom } from "ol/interaction";
import { Vector as VectorLayer } from "ol/layer";

import { vectorLayer, img_wLayer, addZoomListener, createDistrictLayer, setLegendColors } from "./config/config.js";

// 基础状态
let map = null;
const loading = ref(false);
const organId = ref("3306");
const navigationHistory = ref([]);
const currentAreaLevel = ref("county");

// 渲染计数器
let renderCompleteCount = 0;
const RENDER_COMPLETE_THRESHOLD = 3;

const props = defineProps({
  selectedIcon: {
    type: Number,
    default: 1,
  },
});

// 是否显示返回按钮
const canGoBack = computed(() => navigationHistory.value.length > 0);

// 返回上级区域
const goBackToParent = () => {
  if (navigationHistory.value.length > 0) {
    const previousOrganId = navigationHistory.value.pop();
    updateAreaLevel(previousOrganId);
    loading.value = true;
    organId.value = previousOrganId;
  }
};

// 更新区域等级
const updateAreaLevel = (id) => {
  if (!id) return;
  const length = id.length;
  currentAreaLevel.value = length === 4 ? "county" : length === 6 ? "town" : length === 9 ? "village" : "county";
};

// 切换影像图层
const toggleImageLayer = () => {
  img_wLayer.setVisible(!img_wLayer.getVisible());
};

// 监听图例类型变化
watch(
  () => props.selectedIcon,
  (newVal) => {
    if (map) {
      loading.value = true;
      setLegendColors([], map, organId.value, newVal);
      setTimeout(() => (loading.value = false), 500);
    }
  },
  { immediate: true }
);

// 监听区域ID变化
watch(
  () => organId.value,
  async (newVal, oldVal) => {
    if (newVal !== oldVal && map) {
      updateAreaLevel(newVal);
      loading.value = true;
      renderCompleteCount = 0;

      try {
        // 获取并隐藏当前矢量图层
        const vectorLayers = map
          .getLayers()
          .getArray()
          .filter(
            (layer) => layer instanceof VectorLayer && typeof layer.getZIndex === "function" && layer.getZIndex() >= 2
          );

        vectorLayers.forEach((layer) => layer.setVisible(false));

        // 创建新图层
        const districtLayer = await createDistrictLayer(newVal);
        if (!districtLayer) {
          vectorLayers.forEach((layer) => layer.setVisible(true));
          loading.value = false;
          return;
        }

        // 获取特征范围
        const source = districtLayer.getSource();
        if (source && source.getFeatures().length > 0) {
          const extent = source.getExtent();
          const isValidExtent = extent && extent.length === 4 && extent.every((coord) => isFinite(coord));

          if (isValidExtent) {
            // 计算视图参数
            const viewportSize = map.getSize();
            const padding = Array(4).fill(viewportSize[1] * 0.04);
            const maxZoom = newVal.length >= 9 ? 15.5 : 14;

            // 添加图层
            districtLayer.setVisible(false);
            map.addLayer(districtLayer);
            vectorLayers.forEach((layer) => map.removeLayer(layer));

            // 应用颜色设置（简化版本）
            setLegendColors([], map, newVal, props.selectedIcon);

            // 动画过渡
            map.getView().fit(extent, {
              padding,
              duration: 400,
              maxZoom,
            });

            // 完成后显示图层
            setTimeout(() => {
              districtLayer.setVisible(true);
              loading.value = false;
            }, 300);
          } else {
            // 无效范围处理
            districtLayer.setVisible(true);
            map.addLayer(districtLayer);
            vectorLayers.forEach((layer) => map.removeLayer(layer));
            loading.value = false;
          }
        } else {
          // 无特征处理
          districtLayer.setVisible(true);
          map.addLayer(districtLayer);
          vectorLayers.forEach((layer) => map.removeLayer(layer));
          loading.value = false;
        }
      } catch (error) {
        console.error("加载区域图层失败:", error);
        map
          .getLayers()
          .getArray()
          .filter((layer) => layer instanceof VectorLayer)
          .forEach((layer) => layer.setVisible(true));

        loading.value = false;
      }
    }
  }
);

// 初始化地图
onMounted(async () => {
  loading.value = true;
  updateAreaLevel(organId.value);

  // 等待DOM渲染完成
  await nextTick();

  // 创建区域图层
  const districtLayer = await createDistrictLayer(organId.value);
  if (!districtLayer) {
    loading.value = false;
    return;
  }

  // 计算初始视图
  const source = districtLayer.getSource();
  let initialCenter = [120.5825, 29.7971];
  let initialZoom = 10.5;

  if (source && source.getFeatures().length > 0) {
    const extent = source.getExtent();
    if (extent && extent.length === 4 && extent.every((coord) => isFinite(coord))) {
      // 更新中心点和缩放级别
      initialCenter = [(extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2];

      // 根据区域级别设置缩放
      const length = organId.value.length;
      initialZoom = length === 4 ? 10 : length === 6 ? 12 : length === 9 ? 16 : 10.5;
    }
  }

  // 创建地图
  map = new Map({
    target: "map",
    interactions: defaultInteractions()
      .getArray()
      .filter((i) => !(i instanceof DoubleClickZoom)),
    layers: [img_wLayer, districtLayer, vectorLayer],
    view: new View({
      center: initialCenter,
      zoom: initialZoom,
      projection: "EPSG:4326",
      constrainResolution: true,
      maxZoom: 18,
      // minZoom: organId.value.length >= 9 ? 10 : organId.value.length === 6 ? 10.5 : 9.5,
      minZoom: 9,
    }),
    pixelRatio: window.devicePixelRatio > 1 ? 2 : 1,
  });

  // 隐藏影像底图
  img_wLayer.setVisible(false);

  // 调整初始视图
  setTimeout(() => {
    if (source && source.getFeatures().length > 0) {
      const extent = source.getExtent();
      if (extent && extent.length === 4 && extent.every((coord) => isFinite(coord))) {
        const viewportSize = map.getSize();
        const padding = Array(4).fill(viewportSize[1] * 0.15);

        map.getView().fit(extent, {
          padding,
          duration: 500,
          maxZoom: 10,
        });
      }
    }

    // 应用颜色设置（简化版本）
    setLegendColors([], map, organId.value, props.selectedIcon);
  }, 100);

  // 添加点击处理
  map.on("click", (evt) => {
    const feature = map.forEachFeatureAtPixel(evt.pixel, (feature) => feature);
    if (!feature) return;

    // 获取区域ID
    const properties = feature.getProperties();
    let clickedId = properties.bh || properties.id;
    if (properties.properties && (properties.properties.bh || properties.properties.id)) {
      clickedId = clickedId || properties.properties.bh || properties.properties.id;
    }

    const clickedLevel = properties.level || properties.properties?.level || "";

    // 验证区域ID
    if (!clickedId) return;
    if (clickedId === organId.value) return;

    // 检查级别关系
    if (clickedLevel === "village" && currentAreaLevel.value !== "town") return;

    // 执行导航
    loading.value = true;
    navigationHistory.value.push(organId.value);
    organId.value = clickedId;
  });

  // 添加交互监听
  addZoomListener(map);

  // 加载完成处理
  map.on("rendercomplete", () => {
    renderCompleteCount++;
    if (renderCompleteCount >= RENDER_COMPLETE_THRESHOLD) {
      loading.value = false;
      renderCompleteCount = 0;
    }
  });

  map.on("renderstart", () => {
    renderCompleteCount = 0;
  });
});

// 清理资源
onBeforeUnmount(() => {
  if (map) map.setTarget(null);
});

// 暴露组件方法
defineExpose({
  getOrganId: () => organId.value,
  setOrganId: (id) => {
    if (id && id !== organId.value) {
      navigationHistory.value.push(organId.value);
      organId.value = id;
      return true;
    }
    return false;
  },
  getNavigationHistory: () => [...navigationHistory.value],
  goBack: () => {
    if (navigationHistory.value.length > 0) {
      goBackToParent();
      return true;
    }
    return false;
  },
  toggleBaseMap: toggleImageLayer,
  resize: () => {
    if (map) {
      map.updateSize();
    }
  },
});
</script>

<style scoped lang="scss">
.map-container {
  width: 100%;
  height: 100vh; /* 确保容器有固定高度 */
  min-height: 20vh; /* 设置最小高度 */
  position: relative;
  background: transparent;
  overflow: hidden;

  .map-content {
    position: relative;
    width: 100%;
    height: 100%;
    z-index: 1;

    #map {
      width: 100%;
      height: 100%;
      border: none;
      cursor: move;
      box-sizing: border-box;
      overflow: hidden;
      background: #f0f0f0; /* 添加背景色便于调试 */
    }
  }

  .loading-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    font-size: 18px;
    color: #fff;
    z-index: 99;
    backdrop-filter: blur(2px);
    background: rgba(0, 0, 0, 0.3);

    .loading-spinner {
      width: 50px;
      height: 50px;
      margin-bottom: 10px;

      .spinner {
        animation: rotate 1.5s linear infinite;

        circle {
          animation: dash 1.5s ease-in-out infinite;
          stroke-dasharray: 90, 150;
          stroke-dashoffset: 0;
        }
      }
    }

    .loading-text {
      font-weight: 500;
      letter-spacing: 1px;
    }
  }

  .back-button {
    position: absolute;
    top: 30px;
    right: 30px;
    z-index: 10;
    color: white;
    padding: 8px 16px;
    border-radius: 6px;
    display: flex;
    align-items: center;
    cursor: pointer;
    transition: all 0.3s;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
    backdrop-filter: blur(8px);
    background: rgba(27, 54, 129, 0.8);

    &:hover {
      background-color: rgba(27, 54, 129, 1);
      transform: translateY(-2px);
      box-shadow: 0 6px 16px rgba(0, 0, 0, 0.3);
    }

    svg {
      margin-right: 6px;
    }

    span {
      font-size: 14px;
      line-height: 1;
      font-weight: 500;
    }
  }

  @keyframes rotate {
    100% {
      transform: rotate(360deg);
    }
  }

  @keyframes dash {
    0% {
      stroke-dasharray: 1, 150;
      stroke-dashoffset: 0;
    }
    50% {
      stroke-dasharray: 90, 150;
      stroke-dashoffset: -35;
    }
    100% {
      stroke-dasharray: 90, 150;
      stroke-dashoffset: -124;
    }
  }
}
</style>
